//
// Created by Administrator on 2021/5/5.
//

/*
给定一个链表，两两交换其中相邻的节点，并返回交换后的链表。

你不能只是单纯的改变节点内部的值，而是需要实际的进行节点交换。

示例 1：
输入：head = [1,2,3,4]
输出：[2,1,4,3]

示例 2：
输入：head = []
输出：[]

示例 3：
输入：head = [1]
输出：[1]

提示：

链表中节点的数目在范围 [0, 100] 内
0 <= Node.val <= 100

来源：力扣（LeetCode）
链接：https://leetcode-cn.com/problems/swap-nodes-in-pairs
著作权归领扣网络所有。商业转载请联系官方授权，非商业转载请注明出处。*/

#include <iostream>

using namespace std;

//Definition for singly-linked list.
struct ListNode {
    int val;
    ListNode *next;

    ListNode() : val(0), next(nullptr) {}

    ListNode(int x) : val(x), next(nullptr) {}

    ListNode(int x, ListNode *next) : val(x), next(next) {}
};

class Solution {
public:
    ListNode *swapPairs(ListNode *head) {
        auto *dummyHead = new ListNode(0, head); // 哑巴节点
        ListNode *temp = dummyHead; // 临时节点
        while (temp->next != nullptr && temp->next->next != nullptr) { // 下面有连续两个节点 进行交换
            ListNode *node1 = temp->next;
            ListNode *node2 = temp->next->next;
            temp->next = node2;
            node1->next = node2->next;
            node2->next = node1;
            temp = node1; // 临时节点指向末尾
        }
        ListNode *ans = dummyHead->next;
        delete dummyHead;
        return ans;
    }
};

class Solution2 { // 题解 递归
public:
    ListNode *swapPairs(ListNode *head) {
        if (head == nullptr || head->next == nullptr) {
            return head;
        }
        ListNode *newHead = head->next;
        head->next = swapPairs(newHead->next);// 递归调用
        newHead->next = head; // 原本的头节点变成第一个节点
        return newHead;       // 原本的第二个节点变成头节点
    }
};


void printList(ListNode *node) {
    auto firstNode = node;
    do {
        std::cout << firstNode->val << std::endl;
        firstNode = firstNode->next;
    } while (firstNode != nullptr);
}

int main() {
    ListNode n1{1}, n2{2}, n3{3}, n4{4};
    n1.next = &n2;
    n2.next = &n3;
    n3.next = &n4;
    Solution2 sol;
    printList(sol.swapPairs(&n1));
    return 0;
}
